function MainFunction()
global ExperimentParameters;
global ExperimentResults;
global GraphicalObjects;
%%  Sets up the basic parameters of the experiment and configures gage
sampleRate = ExperimentParameters.samplingFrequencies;
fallingTime = ExperimentParameters.dropDurations(ExperimentParameters.dropDurationIndex);
cutTimeAtStartIn_ms = 0; % cut data at the start of drop
CurrentDirectory = pwd;
N_tZCdivising = 20; %added by YJM, 2018.03.28 20��Ƶ
% N_tZCdivising = 1;

[handle, acqinfo, sysinfo] = InitializeGage();
% InitializeSIM;%SIMģ���ʼ�� added by WY, 2018.04.05

%%  Wait for the beginning of the experiment
while(now < ExperimentParameters.startTime)
    pause(1);
    %updates the status text on the measurement tab
    ExperimentResults.instrumentStatus = sprintf('Waiting to start %.0f s', (ExperimentParameters.startTime - now)*24*60*60);
    set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
    if(ExperimentParameters.experimentRunning == 0)
        ExperimentResults.instrumentStatus = 'User stopped.';
        set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
        cd(CurrentDirectory);
        break;
    end
end



%% Set paths to save results
date0=now;

SetResults_all_path = ExperimentParameters.resultsPath;
if(exist(SetResults_all_path)~=7)
    mkdir(SetResults_all_path);
end

DropResults_all_path = ExperimentParameters.resultsPath;
if(exist(DropResults_all_path)~=7)
    mkdir(DropResults_all_path);
end

SetResults_path = strcat(SetResults_all_path,'\', datestr(date0, 'yyyy-mm-dd HH-MM-SS'));
if(exist(SetResults_path)~=7)
    mkdir(SetResults_path);
end

DropResults_path = strcat(DropResults_all_path,'\',datestr(date0, 'yyyy-mm-dd HH-MM-SS'));
if(exist(DropResults_path)~=7)
    mkdir(DropResults_path);
end

%% Creat files to save results
cd(SetResults_all_path);
fid00 = fopen('Set_Results_all.dat','a+');
fclose(fid00);
cd(CurrentDirectory);

cd(DropResults_all_path);
fid01 = fopen('Drop_Results_all.dat','a+');
fclose(fid01);
cd(CurrentDirectory);

cd(SetResults_path);
fid0 = fopen('Set_Results.dat','a+');
fclose(fid0);
cd(CurrentDirectory);

cd(DropResults_path);
fid1 = fopen('Drop_Results.dat','a+');
fclose(fid0);
cd(CurrentDirectory);

%%  Main loop of the experiment
number_of_set = 1;

    %% check if the experiment shouldn't finish already
if( now > ExperimentParameters.stopTime && ExperimentParameters.infiniteLoop == 0);
    ExperimentResults.instrumentStatus = 'End of experiment';
    set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
    btnStartStop = findobj('Tag', 'btnStartStop');
    set(btnStartStop, 'Value', get(btnStartStop, 'Min'), 'String', 'Start');
    cd(CurrentDirectory);
    return;
end
    %% calculate the time of next set of drops
    %timeOfNextDrop = datevec(datenum(0,0,0,0,0,ExperimentParameters.timeBetweenSets)) + clock;

    
    %% motor_zero per set (added by WY 20201003)
    motor_zero_maxon;% You should check the serial port number every time the program is run on a new computer
    pause(13);% homing upwards
    %pause(13);% homing downwards
    %}
    failedDropsNr = 0;
    fprintf('Set #%.2i\n', number_of_set);
    ExperimentResults.SingleDrop.dropNumber = 1;
    dropResults=[];     
while (ExperimentParameters.experimentRunning == 1 && ExperimentParameters.TriggerNormal == 1)
    %% check if the experiment shouldn't finish already
    if( now > ExperimentParameters.stopTime && ExperimentParameters.infiniteLoop == 0);
        ExperimentResults.instrumentStatus = 'End of experiment';
        set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
        btnStartStop = findobj('Tag', 'btnStartStop');
        set(btnStartStop, 'Value', get(btnStartStop, 'Min'), 'String', 'Start');
        cd(CurrentDirectory);
        break;
    end
    
    %% aquire data and calculate
    
    fprintf('Drop %.2i\n',ExperimentResults.SingleDrop.dropNumber);
    fprintf('******************************************** \n');
    
    if(ExperimentParameters.experimentRunning == 0);
        ExperimentResults.instrumentStatus = 'User broke the measurement';
        set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
        cd(CurrentDirectory);
        break;
    end

    while(ExperimentParameters.Click==0 &&ExperimentParameters.experimentRunning == 1 )
        pause(0.5);
    end
%     while(ExperimentResults.SingleDrop.dropNumber <= ExperimentParameters.dropsPerSet)
    if(ExperimentParameters.Click==1)
        ExperimentParameters.Click=0;
        %% Acquires data, drives the motor, and GAGE cards

        tstart=tic;

        while(toc(tstart)<18)
            try
                while (ExperimentParameters.Drop==0)
                    ExperimentParameters.Drop=Prediction();  %����Ԥ��
                end
                [data,compensation] = Data_Acquisition(handle, acqinfo);
                date = now;
                pause(1);
                break;
            catch
                if(toc(tstart)>=10)
                    fprintf('Experiment failed. No Trigger signal!!!\n');
                    ExperimentResults.instrumentStatus = 'Experiment failed. No Trigger!';
                    set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);                 
                    data=[];

                else
                    continue;
                end
            end
        end

        %% judge if the trigger is normal
        if(ExperimentParameters.TriggerNormal == 0)
            break;
        end

        %%
        ExperimentResults.instrumentStatus = 'Data processing';
        set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
        resultsCalculated = 0;

        if isempty(data)
            
        else
        %% calculate tZC, gZC and Residuals
        fprintf('�ɼ���ԭʼ���ֵ�� %f \n',max(data)-min(data));
        compensation=compensation*3.5;
        data=data*3.5;
        [tZC, strResiduals, gZC, se_g] = Calculate(data, cutTimeAtStartIn_ms);        
        figure(5)
        plot(compensation)
%         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%         %% save data, added by YJM, 2019.12.02
%         % length of data = 100e6*duration
%         try
%             laser_data_folder = strcat('data_of_set_',num2str(number_of_set));
%             laser_data_path = strcat(DropResults_path,'\',laser_data_folder);
%             if(exist(laser_data_path)~=7)
%                 mkdir(laser_data_path);
%             end
%             cd(laser_data_path);
%             laser_data_file = strcat('Drop_',num2str(ExperimentResults.SingleDrop.dropNumber),' laser_data','.mat');
%             save(laser_data_file,'data');
%             cd(CurrentDirectory);
%         catch
%             disp('data saving error!');
%         end
%         %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
        
        %% added by YJM, 2018.03.22
        % calculate tZC divised by N_tZCdivising
        try
            tZC_divised = zeros(floor(length(tZC)/N_tZCdivising),1);
            tZC_divised(1) = tZC(1);
            for i = 2:1:length(tZC)
                if ~rem(i-1, N_tZCdivising)
                    tZC_divised((i-1)/N_tZCdivising+1) = tZC(i);
                end
            end
            tZC_divised = tZC_divised(:);
        catch
            disp('tZC_divised calculating error!');
        end        
        
        %% store the calculate results
        ExperimentResults.SingleDrop.currentGValue = gZC;
        dropResults(ExperimentResults.SingleDrop.dropNumber).gZC = ExperimentResults.SingleDrop.currentGValue;
        dropResults(ExperimentResults.SingleDrop.dropNumber).strResiduals = std(strResiduals)*1e9;
        dropResults(ExperimentResults.SingleDrop.dropNumber).date = date;
        
        %2017.11.30 add se_g
        dropResults(ExperimentResults.SingleDrop.dropNumber).se_g = se_g;              
        
        dropResults(ExperimentResults.SingleDrop.dropNumber).tideVal = SolidTidesInfluence(dropResults(ExperimentResults.SingleDrop.dropNumber).date,...
            ExperimentParameters.Location.latitude,ExperimentParameters.Location.longitude,ExperimentParameters.Location.height);
                
        gExp = ExperimentParameters.corrections.ExpectedGValue;
        gTol = ExperimentParameters.corrections.GValueTolerance;
        i = 1;
        g = [];
        Date = [];
        tideVal = [];
        while i <=length(dropResults)
            if abs(dropResults(i).gZC - gExp) < gTol
                g = [g dropResults(i).gZC];
                Date = [Date dropResults(i).date];
                tideVal = [tideVal dropResults(i).tideVal];
            end
            i = i+1;
        end
        failedDropsNr = length(dropResults)-length(g);
        
        resultsCalculated = 1;

        if(~isempty(g))
            ExperimentResults.SingleDrop.meanGValueOfSet = mean(g);
            ExperimentResults.SingleDrop.standardDeviation = std(g);
            ExperimentResults.SingleDrop.standardError = ExperimentResults.SingleDrop.standardDeviation/sqrt(ExperimentResults.SingleDrop.dropNumber);
            gCorrected = g-tideVal;
            ExperimentResults.SingleDrop.correctedMeanGValue = mean(gCorrected);
            ExperimentResults.SingleDrop.solidTidesCorrection = mean(tideVal);
        end

        %% update single drop talbe
        set(findobj('Tag', 'editSingleDropDropNumber'), 'String',ExperimentResults.SingleDrop.dropNumber);
        set(findobj('Tag', 'editSingleDropCurrentGValue'), 'String',num2str(ExperimentResults.SingleDrop.currentGValue,10));
        set(findobj('Tag', 'editSetmeanZCGValue'), 'String',num2str(ExperimentResults.SingleDrop.meanGValueOfSet,10));
        set(findobj('Tag', 'editSetMeanSolidTidesCorrection'), 'String',num2str(ExperimentResults.SingleDrop.solidTidesCorrection,'%.2f'));
        set(findobj('Tag', 'editStdDevMeanZCGValue'), 'String',num2str(ExperimentResults.SingleDrop.standardDeviation,'%.2f'));
        set(findobj('Tag', 'editStandardErrorMZCMeanGValue'), 'String',num2str(ExperimentResults.SingleDrop.standardError,'%.2f'));

        %% save drop results
        cd(DropResults_path);
        fid1 = fopen('Drop_Results.dat','a+');
        fprintf(fid1, '%9.2f \t %3.2f \t %9.2f \t %3.3f \t %2.3f \t %s \n',...
            dropResults(ExperimentResults.SingleDrop.dropNumber).gZC,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).tideVal,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).gZC-dropResults(ExperimentResults.SingleDrop.dropNumber).tideVal,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).strResiduals,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).se_g,...
            datestr(dropResults(ExperimentResults.SingleDrop.dropNumber).date, 'yyyy-mm-dd HH:MM:SS'));
        fclose(fid1);
        cd(CurrentDirectory);

       %%  Plot the original residuals
        Env=PlotDropResutls(data, tZC, strResiduals, g); %����
        
        %% save tZC, divised by N_tZCdivising, added by YJM, 2018.03.22
        try
            tZC_divised_folder = strcat('tZC_of_set_',num2str(number_of_set),' divise_by_',num2str(N_tZCdivising));
            tZC_divised_path = strcat(DropResults_path,'\',tZC_divised_folder);
            if(exist(tZC_divised_path)~=7)
                mkdir(tZC_divised_path);
            end
            cd(tZC_divised_path);
            
%             tZC_divised_file = strcat('Drop_',num2str(ExperimentResults.SingleDrop.dropNumber),' tZC_data','.dat');
%             fid_tZC = fopen(tZC_divised_file,'a+');
%             for i=1:1:length(tZC_divised)
%                 fprintf(fid_tZC, '%2.9f \n', tZC_divised(i));
%             end
%             fclose(fid_tZC);
%             
%             tZC_divised_bin = strcat('Drop_',num2str(ExperimentResults.SingleDrop.dropNumber),' tZC','.bin');
%             fid_tZC_bin = fopen(tZC_divised_bin,'a+');
%             for i=1:1:length(tZC_divised)
%                 fwrite(fid_tZC_bin, tZC_divised(i),'double');
%             end
%             fclose(fid_tZC_bin);

            laser_data_file = strcat('Drop_',num2str(ExperimentResults.SingleDrop.dropNumber),' laser_data','.mat');
            save(laser_data_file,'data');
            envelope_file = strcat('Drop_',num2str(ExperimentResults.SingleDrop.dropNumber),' compensation','.mat');
            save(envelope_file,'compensation');
%             fid_laser = fopen(laser_data_file,'a+');
%             for i=1:1:length(data)
%                 fprintf(fid_laser, '%2.9f \n', data(i));
%             end
%             fclose(fid_laser);
            
            cd(CurrentDirectory);
        catch
            disp('tZC saving error!');
        end

        cd(DropResults_all_path);
        fid01 = fopen('Drop_Results_all.dat','a+');
        fprintf(fid01, '%9.2f \t %3.2f \t %9.2f \t %3.3f \t %2.3f \t %s \n',...
            dropResults(ExperimentResults.SingleDrop.dropNumber).gZC,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).tideVal,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).gZC-dropResults(ExperimentResults.SingleDrop.dropNumber).tideVal,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).strResiduals,...
            dropResults(ExperimentResults.SingleDrop.dropNumber).se_g,...% 2017.11.30
            datestr(dropResults(ExperimentResults.SingleDrop.dropNumber).date, 'yyyy-mm-dd HH:MM:SS'));
        fclose(fid01);
        cd(CurrentDirectory);



        %% clear data chunk to save memory
        clear data;
        clear tZC;
        clear strResiduals;

        ExperimentResults.SingleDrop.dropNumber = ExperimentResults.SingleDrop.dropNumber + 1;
        end
        %% check if user didn't stop the experiment
        if(ExperimentParameters.experimentRunning == 0);
            ExperimentResults.instrumentStatus = 'User broke the measurement';
            set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
            cd(CurrentDirectory);
            break;
        end
    end;

    %% judge if the trigger is normal
    if(ExperimentParameters.TriggerNormal == 0)
        break;
    end
end;
    %% store the set results
    ExperimentResults.Results.dropsTotal = ExperimentResults.Results.dropsTotal+ExperimentResults.SingleDrop.dropNumber-1;
    ExperimentResults.Results.faildDropsTotal = ExperimentResults.Results.faildDropsTotal+failedDropsNr;
    ExperimentResults.Results.dropsRejected = (ExperimentResults.Results.faildDropsTotal/ExperimentResults.Results.dropsTotal)*100;%100%
    sets_meanG = [];
    sets_correctedMeanG = [];
    sets_solidTidesCorrection = [];
    sets_errorbar = [];
    if(~isempty(g))
        setResults(number_of_set).meanG = ExperimentResults.SingleDrop.meanGValueOfSet;
        setResults(number_of_set).correctedMeanG=ExperimentResults.SingleDrop.correctedMeanGValue;
        setResults(number_of_set).solidTidesCorrection=ExperimentResults.SingleDrop.solidTidesCorrection;
        setResults(number_of_set).errorbar=ExperimentResults.SingleDrop.standardError;
        i=1;
        while i <=length(setResults)
            sets_meanG = [sets_meanG setResults(i).meanG];
            sets_correctedMeanG = [sets_correctedMeanG setResults(i).correctedMeanG];
            sets_solidTidesCorrection = [sets_solidTidesCorrection setResults(i).solidTidesCorrection];
            sets_errorbar = [sets_errorbar setResults(i).errorbar];
            i = i+1;
        end
        ExperimentResults.Results.meanGValue = mean(sets_meanG);
        ExperimentResults.Results.correctedMeanGValue = mean(sets_correctedMeanG);
        %         ExperimentResults.Results.standardDeviation = std(sets_meanG);
        ExperimentResults.Results.standardDeviation = std(sets_correctedMeanG);%% by LG 2013.09.29
        ExperimentResults.Results.standardError = ExperimentResults.Results.standardDeviation/sqrt(number_of_set);

        %% update long term measurement results talbe
        set(findobj('Tag', 'editSetNumber'), 'String',number_of_set);
        set(findobj('Tag', 'editResultsMeanGValue'), 'String',num2str(ExperimentResults.Results.meanGValue,10));
        set(findobj('Tag', 'editResultsStandardDeviation'), 'String',num2str(ExperimentResults.Results.standardDeviation,'%.2f'));
        set(findobj('Tag', 'editResultsStandardError'), 'String',num2str(ExperimentResults.Results.standardError,'%.2f'));
        set(findobj('Tag', 'editResultsCorrectedMeanGValue'), 'String',num2str(ExperimentResults.Results.correctedMeanGValue,10));
        set(findobj('Tag', 'editResultsDropsTotal'), 'String',ExperimentResults.Results.dropsTotal);
        set(findobj('Tag', 'editResultsDropsRejected'), 'String',num2str(ExperimentResults.Results.dropsRejected,'%.2f'));

        %% save the set results
        cd(SetResults_path);
        fid0 = fopen('Set_Results.dat','a+');
        fprintf(fid0, '%9.2f \t %3.2f \t %9.2f \t %3.2f \t %3.2f \t %s\n',...
            setResults(number_of_set).meanG,...
            setResults(number_of_set).solidTidesCorrection,...
            setResults(number_of_set).correctedMeanG,...
            ExperimentResults.SingleDrop.standardDeviation,...
            ExperimentResults.SingleDrop.standardError,...
            datestr(dropResults(1).date, 'yyyy-mm-dd HH:MM:SS'));
        fclose(fid0);
        cd(CurrentDirectory);

        cd(SetResults_all_path);
        fid00 = fopen('Set_Results_all.dat','a+');
        fprintf(fid00, '%9.2f \t %3.2f \t %9.2f \t %3.2f \t %3.2f \t %s\n',...
            setResults(number_of_set).meanG,...
            setResults(number_of_set).solidTidesCorrection,...
            setResults(number_of_set).correctedMeanG,...
            ExperimentResults.SingleDrop.standardDeviation,...
            ExperimentResults.SingleDrop.standardError,...
            datestr(dropResults(1).date, 'yyyy-mm-dd HH:MM:SS'));
        fclose(fid00);
        cd(CurrentDirectory);
    end

    %% plot set g values and solid tides influence
    axes (GraphicalObjects.axesResultsGValues);
    hold off;
    PlotSetResults(sets_correctedMeanG, sets_meanG, sets_errorbar, sets_solidTidesCorrection);
    cd(SetResults_path);
    f=getframe(gcf);
    f_name=strcat(num2str(number_of_set),'set.png');
    imwrite(f.cdata,f_name);
    cd(CurrentDirectory);
    %% clear data chunk to avoid interfering the mearments of the next set
    clear dropResults;
    number_of_set = number_of_set+1;
    
    %% WaitForNextDrop(timeOfNextDrop);
%     try
%         %wait for some time to perform next series of drops
%         while( now<datenum(timeOfNextDrop) )
%             pause(1);
%             ExperimentResults.instrumentStatus = sprintf('Waiting %.0f s', (datenum(timeOfNextDrop) - now)*24*60*60);
%             set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
%             if( now > ExperimentParameters.stopTime && ExperimentParameters.infiniteLoop == 0)
%                 ExperimentResults.instrumentStatus = 'End of experiment.';
%                 btnStartStop = findobj('Tag', 'btnStartStop');
%                 set(btnStartStop, 'Value', get(btnStartStop, 'Min'),  'String', 'Start');
%                 set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
%                 cd(CurrentDirectory);
%                 break;
%             end
%             if(ExperimentParameters.experimentRunning == 0)
%                 ExperimentResults.instrumentStatus = 'User stopped.';
%                 set(findobj('Tag', 'editInstrumentStatus'), 'String',ExperimentResults.instrumentStatus);
%                 cd(CurrentDirectory);
%                 break;
%             end
%         end;
%     catch
%     end


%% Set the value of the BtnStartStop
if(ExperimentParameters.TriggerNormal == 0)
    btnStartStop = findobj('Tag', 'btnStartStop');
    set(btnStartStop, 'Value', get(btnStartStop, 'Min'),  'String', 'Start');
    cd(CurrentDirectory);
end
end
